/***********************************************************************  
 *   @package：cn.wj.base.controller，@class-name：BaseController.java   
 *   @copyright     Copyright:   2015-2016     
 *   @creator       wenjie 
 *   @create-time   2016年1月5日   下午4:23:14   
 *   @revision      $Id: 1.0    
 ***********************************************************************/
package cn.wj.base.controller;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.wj.base.annotation.Packing;
import cn.wj.base.annotation.RequestMapping;

public class BaseController extends HttpServlet {
	private HttpServletRequest request;

	private static final long serialVersionUID = 1L;

	@Override
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
			setRequest(request);
			String controllerMrthod = request.getParameter("WJFrameWorkMethod");
			try {
				if(controllerMrthod!=null){
					Method[] classMethods = getClass().getDeclaredMethods();
					boolean haveMethod = false;
		/////////////////////
					for (Method method : classMethods) {
						RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
						if(requestMapping==null) continue;
						if (controllerMrthod.equals(requestMapping.method())) {
							List<Object> list = new ArrayList<Object>();
							//无法直接获取得到方法的参数名称和类型
							Annotation[][] annotationss = method.getParameterAnnotations();
							for (Annotation[] annotations : annotationss) {
								for (Annotation annotation : annotations) {
									if (Packing.class.isInstance(annotation)) {
										Packing packing = (Packing) annotation;
										list.addAll(setPgetParameter(packing, request));
									}
								}

							}
							list.add(request);
							list.add(response);
							String result = (String) method.invoke(this, list.toArray());
							if (requestMapping.isAjax()) {
								response.setCharacterEncoding("UTF-8");
								response.getWriter().write(result);
								response.getWriter().close();
							} else if (requestMapping.auto()) {
								request.getRequestDispatcher(result).forward(request, response);
							}
							haveMethod = true;
							break;
						}
					}
		/////////////////////
					if (!haveMethod) {
						response.getWriter().write("Sorry,didn't find the " + controllerMrthod + " method ! requestMapping is error");
						response.getWriter().close();
					}
				} 
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
 

	private List<Object> setPgetParameter(Packing p, HttpServletRequest request)
			throws InstantiationException, IllegalAccessException {
		List<Object> list = new ArrayList<Object>();
		if (p.type().isArray()) { 		// 是数组
			CommonType commonType = CommonType.help.setType(p.type().getComponentType());
			if (commonType == null) {   // 数组里面装的 复杂类型 ｛user1，user2｝
				Class<?> clazz = p.type().getComponentType();
				Map<Field, String[]> ParameterMap = new HashMap<Field, String[]>();
				int count = 0;
				for (Field field : clazz.getDeclaredFields()) {
					String[] parameterValue = request.getParameterValues(field.getName());
					ParameterMap.put(field, parameterValue);
					if (parameterValue != null) {
						count = parameterValue.length > count ? parameterValue.length : count;
					}
				}
				Object entity = null;
				Object array = Array.newInstance(clazz, count);
				for (int i = 0; i < count; i++) {
					entity = clazz.newInstance();
					for (Entry<Field, String[]> entrySet : ParameterMap.entrySet()) {
						Field field = entrySet.getKey();
						String[] values = entrySet.getValue();
						if (values == null || values.length == 0)
							continue;
						CommonType pType = CommonType.help.setType(field.getType());
						if (i < values.length) {
							field.setAccessible(true);
							field.set(entity, pType.getValue(values[i]));
						}
					}
					Array.set(array, i, entity);
				}
				list.add(array);
			} else {  // 数组里面装的 基本类型 ｛1，2，3｝
				String[] Parameters = request.getParameterValues(p.name());
				if(Parameters!=null && Parameters.length>0){
					Class<?> clazz=p.type().getComponentType();
					Object array = Array.newInstance(clazz, Parameters.length);  
					for (int i=0;i<Parameters.length;i++ ) {
						Array.set(array,i, commonType.getValue(Parameters[i]));  
					}
					list.add(array);
				}else{
					list.add(null);
				}
			}
		} else {// 非数组
			CommonType commonType = CommonType.help.setType(p.type());
			if (commonType == null) { // 装的复杂类型 user
				Class<?> clazz = p.type();
				List<String> valueList = new ArrayList<String>();
				Field[] fields = clazz.getDeclaredFields();
				for (Field field : fields) {
					valueList.add(request.getParameter(field.getName()));
				}
				Object entity = clazz.newInstance();
				for (int i = 0; i < fields.length; i++) {
					CommonType pType = CommonType.help.setType(fields[i].getType());
					if(pType!=null){
						Field field = fields[i];
						field.setAccessible(true);
						field.set(entity, pType.getValue(valueList.get(i)));
					}
				}
				list.add(entity);
			} else { // 里面装的 基本类型 1
				String Parameter = request.getParameter(p.name());
				list.add(commonType.getValue(Parameter));
			}
		}
		return list;
	}

	public HttpServletRequest getRequest() {
		return request;
	}

	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}

	protected void addAttribute(String name, Object value) {
		getRequest().setAttribute(name, value);
	}

	protected Object getAttribute(String name) {
		return getRequest().getAttribute(name);
	}
	protected Object getSession(String name) {
		return request.getSession().getAttribute(name);
	}
	protected void setSession(String name, Object value) {
		request.getSession().setAttribute(name, value);;
	}
	protected void removeSession(String name) {
		request.getSession().removeAttribute(name);
	}
	

}
